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.cs986
1 files changed, 797 insertions, 189 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1c276fa..c108129 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
@@ -110,6 +113,7 @@ namespace OpenSim.Region.Framework.Scenes
110 { 113 {
111 get { return m_attachments; } 114 get { return m_attachments; }
112 } 115 }
116
113 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 117 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
114 118
115 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); 119 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
@@ -121,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
121 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
122 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
123 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
124 128
129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
125 private Vector3 m_lastPosition; 131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
126 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
127 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
128 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -130,6 +137,11 @@ namespace OpenSim.Region.Framework.Scenes
130 private bool m_updateflag; 137 private bool m_updateflag;
131 private byte m_movementflag; 138 private byte m_movementflag;
132 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
140 private int m_userFlags;
141 public int UserFlags
142 {
143 get { return m_userFlags; }
144 }
133 private TeleportFlags m_teleportFlags; 145 private TeleportFlags m_teleportFlags;
134 public TeleportFlags TeleportFlags 146 public TeleportFlags TeleportFlags
135 { 147 {
@@ -160,9 +172,10 @@ namespace OpenSim.Region.Framework.Scenes
160 private int m_perfMonMS; 172 private int m_perfMonMS;
161 173
162 private bool m_setAlwaysRun; 174 private bool m_setAlwaysRun;
163
164 private bool m_forceFly; 175 private bool m_forceFly;
165 private bool m_flyDisabled; 176 private bool m_flyDisabled;
177 private bool m_flyingOld; // add for fly velocity control
178 public bool m_wasFlying; // add for fly velocity control
166 179
167 private float m_speedModifier = 1.0f; 180 private float m_speedModifier = 1.0f;
168 181
@@ -181,7 +194,8 @@ namespace OpenSim.Region.Framework.Scenes
181 protected RegionInfo m_regionInfo; 194 protected RegionInfo m_regionInfo;
182 protected ulong crossingFromRegion; 195 protected ulong crossingFromRegion;
183 196
184 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 197 private readonly Vector3[] Dir_Vectors = new Vector3[11];
198 private bool m_isNudging = false;
185 199
186 // Position of agent's camera in world (region cordinates) 200 // Position of agent's camera in world (region cordinates)
187 protected Vector3 m_CameraCenter; 201 protected Vector3 m_CameraCenter;
@@ -206,17 +220,25 @@ namespace OpenSim.Region.Framework.Scenes
206 private bool m_autopilotMoving; 220 private bool m_autopilotMoving;
207 private Vector3 m_autoPilotTarget; 221 private Vector3 m_autoPilotTarget;
208 private bool m_sitAtAutoTarget; 222 private bool m_sitAtAutoTarget;
223 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
209 224
210 private string m_nextSitAnimation = String.Empty; 225 private string m_nextSitAnimation = String.Empty;
211 226
212 //PauPaw:Proper PID Controler for autopilot************ 227 //PauPaw:Proper PID Controler for autopilot************
213 private bool m_moveToPositionInProgress; 228 private bool m_moveToPositionInProgress;
214 private Vector3 m_moveToPositionTarget; 229 private Vector3 m_moveToPositionTarget;
230 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
215 231
216 private bool m_followCamAuto; 232 private bool m_followCamAuto;
217 233
218 private int m_movementUpdateCount; 234 private int m_movementUpdateCount;
235 private int m_lastColCount = -1; //KF: Look for Collision chnages
236 private int m_updateCount = 0; //KF: Update Anims for a while
237 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
219 private const int NumMovementsBetweenRayCast = 5; 238 private const int NumMovementsBetweenRayCast = 5;
239 private List<uint> m_lastColliders = new List<uint>();
240
241 private object m_syncRoot = new Object();
220 242
221 private bool CameraConstraintActive; 243 private bool CameraConstraintActive;
222 //private int m_moveToPositionStateStatus; 244 //private int m_moveToPositionStateStatus;
@@ -243,7 +265,9 @@ namespace OpenSim.Region.Framework.Scenes
243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 265 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 266 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 267 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
246 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 268 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
269 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
270 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
247 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 271 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
248 } 272 }
249 273
@@ -450,7 +474,8 @@ namespace OpenSim.Region.Framework.Scenes
450 get 474 get
451 { 475 {
452 PhysicsActor actor = m_physicsActor; 476 PhysicsActor actor = m_physicsActor;
453 if (actor != null) 477// if (actor != null)
478 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
454 m_pos = actor.Position; 479 m_pos = actor.Position;
455 else 480 else
456 { 481 {
@@ -499,7 +524,8 @@ namespace OpenSim.Region.Framework.Scenes
499 } 524 }
500 } 525 }
501 526
502 m_pos = value; 527 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
528 m_pos = value;
503 m_parentPosition = Vector3.Zero; 529 m_parentPosition = Vector3.Zero;
504 } 530 }
505 } 531 }
@@ -543,10 +569,39 @@ namespace OpenSim.Region.Framework.Scenes
543 } 569 }
544 } 570 }
545 571
572 public Quaternion OffsetRotation
573 {
574 get { return m_offsetRotation; }
575 set { m_offsetRotation = value; }
576 }
577
546 public Quaternion Rotation 578 public Quaternion Rotation
547 { 579 {
548 get { return m_bodyRot; } 580 get {
549 set { m_bodyRot = value; } 581 if (m_parentID != 0)
582 {
583 if (m_offsetRotation != null)
584 {
585 return m_offsetRotation;
586 }
587 else
588 {
589 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
590 }
591
592 }
593 else
594 {
595 return m_bodyRot;
596 }
597 }
598 set {
599 m_bodyRot = value;
600 if (m_parentID != 0)
601 {
602 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
603 }
604 }
550 } 605 }
551 606
552 public Quaternion PreviousRotation 607 public Quaternion PreviousRotation
@@ -571,11 +626,21 @@ namespace OpenSim.Region.Framework.Scenes
571 626
572 private uint m_parentID; 627 private uint m_parentID;
573 628
629
630 private UUID m_linkedPrim;
631
574 public uint ParentID 632 public uint ParentID
575 { 633 {
576 get { return m_parentID; } 634 get { return m_parentID; }
577 set { m_parentID = value; } 635 set { m_parentID = value; }
578 } 636 }
637
638 public UUID LinkedPrim
639 {
640 get { return m_linkedPrim; }
641 set { m_linkedPrim = value; }
642 }
643
579 public float Health 644 public float Health
580 { 645 {
581 get { return m_health; } 646 get { return m_health; }
@@ -697,7 +762,7 @@ namespace OpenSim.Region.Framework.Scenes
697 CreateSceneViewer(); 762 CreateSceneViewer();
698 m_animator = new ScenePresenceAnimator(this); 763 m_animator = new ScenePresenceAnimator(this);
699 } 764 }
700 765
701 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 766 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
702 { 767 {
703 m_rootRegionHandle = reginfo.RegionHandle; 768 m_rootRegionHandle = reginfo.RegionHandle;
@@ -711,6 +776,7 @@ namespace OpenSim.Region.Framework.Scenes
711 m_localId = m_scene.AllocateLocalId(); 776 m_localId = m_scene.AllocateLocalId();
712 777
713 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 778 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
779 m_userFlags = account.UserFlags;
714 780
715 if (account != null) 781 if (account != null)
716 m_userLevel = account.UserLevel; 782 m_userLevel = account.UserLevel;
@@ -729,10 +795,7 @@ namespace OpenSim.Region.Framework.Scenes
729 m_reprioritization_timer.AutoReset = false; 795 m_reprioritization_timer.AutoReset = false;
730 796
731 AdjustKnownSeeds(); 797 AdjustKnownSeeds();
732
733 // TODO: I think, this won't send anything, as we are still a child here...
734 Animator.TrySetMovementAnimation("STAND"); 798 Animator.TrySetMovementAnimation("STAND");
735
736 // we created a new ScenePresence (a new child agent) in a fresh region. 799 // we created a new ScenePresence (a new child agent) in a fresh region.
737 // Request info about all the (root) agents in this region 800 // Request info about all the (root) agents in this region
738 // Note: This won't send data *to* other clients in that region (children don't send) 801 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -783,25 +846,47 @@ namespace OpenSim.Region.Framework.Scenes
783 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 846 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
784 Dir_Vectors[4] = Vector3.UnitZ; //UP 847 Dir_Vectors[4] = Vector3.UnitZ; //UP
785 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 848 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
786 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 849 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
787 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 850 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
788 Dir_Vectors[7] = -Vector3.UnitX; //BACK 851 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
852 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
853 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
789 } 854 }
790 855
791 private Vector3[] GetWalkDirectionVectors() 856 private Vector3[] GetWalkDirectionVectors()
792 { 857 {
793 Vector3[] vector = new Vector3[9]; 858 Vector3[] vector = new Vector3[11];
794 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 859 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
795 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 860 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
796 vector[2] = Vector3.UnitY; //LEFT 861 vector[2] = Vector3.UnitY; //LEFT
797 vector[3] = -Vector3.UnitY; //RIGHT 862 vector[3] = -Vector3.UnitY; //RIGHT
798 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 863 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
799 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 864 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
800 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 865 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
801 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 866 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
802 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 867 vector[8] = Vector3.UnitY; //LEFT_NUDGE
868 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
869 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
803 return vector; 870 return vector;
804 } 871 }
872
873 private bool[] GetDirectionIsNudge()
874 {
875 bool[] isNudge = new bool[11];
876 isNudge[0] = false; //FORWARD
877 isNudge[1] = false; //BACK
878 isNudge[2] = false; //LEFT
879 isNudge[3] = false; //RIGHT
880 isNudge[4] = false; //UP
881 isNudge[5] = false; //DOWN
882 isNudge[6] = true; //FORWARD_NUDGE
883 isNudge[7] = true; //BACK_NUDGE
884 isNudge[8] = true; //LEFT_NUDGE
885 isNudge[9] = true; //RIGHT_NUDGE
886 isNudge[10] = true; //DOWN_Nudge
887 return isNudge;
888 }
889
805 890
806 #endregion 891 #endregion
807 892
@@ -863,6 +948,54 @@ namespace OpenSim.Region.Framework.Scenes
863 pos.Y = crossedBorder.BorderLine.Z - 1; 948 pos.Y = crossedBorder.BorderLine.Z - 1;
864 } 949 }
865 950
951 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
952 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
953 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
954 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
955 if (land != null)
956 {
957 if (KnownChildRegionHandles.Count == 0)
958 {
959 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
960 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)
961 {
962 pos = land.LandData.UserLocation;
963 }
964 }
965
966 land.SendLandUpdateToClient(ControllingClient);
967 }
968
969 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
970 {
971 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
972
973 if (pos.X < 0)
974 {
975 emergencyPos.X = (int)Constants.RegionSize + pos.X;
976 if (!(pos.Y < 0))
977 emergencyPos.Y = pos.Y;
978 if (!(pos.Z < 0))
979 emergencyPos.Z = pos.Z;
980 }
981 if (pos.Y < 0)
982 {
983 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
984 if (!(pos.X < 0))
985 emergencyPos.X = pos.X;
986 if (!(pos.Z < 0))
987 emergencyPos.Z = pos.Z;
988 }
989 if (pos.Z < 0)
990 {
991 emergencyPos.Z = 128;
992 if (!(pos.Y < 0))
993 emergencyPos.Y = pos.Y;
994 if (!(pos.X < 0))
995 emergencyPos.X = pos.X;
996 }
997 }
998
866 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 999 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
867 { 1000 {
868 m_log.WarnFormat( 1001 m_log.WarnFormat(
@@ -991,12 +1124,17 @@ namespace OpenSim.Region.Framework.Scenes
991 { 1124 {
992 if (PhysicsActor != null) 1125 if (PhysicsActor != null)
993 { 1126 {
994 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1127 try
995 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1128 {
996 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1129 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
997 m_physicsActor.UnSubscribeEvents(); 1130 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
998 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1131 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
999 PhysicsActor = null; 1132 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1133 m_physicsActor.UnSubscribeEvents();
1134 PhysicsActor = null;
1135 }
1136 catch
1137 { }
1000 } 1138 }
1001 } 1139 }
1002 1140
@@ -1007,9 +1145,10 @@ namespace OpenSim.Region.Framework.Scenes
1007 public void Teleport(Vector3 pos) 1145 public void Teleport(Vector3 pos)
1008 { 1146 {
1009 bool isFlying = false; 1147 bool isFlying = false;
1148
1010 if (m_physicsActor != null) 1149 if (m_physicsActor != null)
1011 isFlying = m_physicsActor.Flying; 1150 isFlying = m_physicsActor.Flying;
1012 1151
1013 RemoveFromPhysicalScene(); 1152 RemoveFromPhysicalScene();
1014 Velocity = Vector3.Zero; 1153 Velocity = Vector3.Zero;
1015 AbsolutePosition = pos; 1154 AbsolutePosition = pos;
@@ -1021,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes
1021 } 1160 }
1022 1161
1023 SendTerseUpdateToAllClients(); 1162 SendTerseUpdateToAllClients();
1163
1024 } 1164 }
1025 1165
1026 public void TeleportWithMomentum(Vector3 pos) 1166 public void TeleportWithMomentum(Vector3 pos)
@@ -1239,6 +1379,7 @@ namespace OpenSim.Region.Framework.Scenes
1239 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1379 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1240 1380
1241 m_pos = m_LastFinitePos; 1381 m_pos = m_LastFinitePos;
1382
1242 if (!m_pos.IsFinite()) 1383 if (!m_pos.IsFinite())
1243 { 1384 {
1244 m_pos.X = 127f; 1385 m_pos.X = 127f;
@@ -1305,7 +1446,6 @@ namespace OpenSim.Region.Framework.Scenes
1305 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1446 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1306 } 1447 }
1307 } 1448 }
1308
1309 lock (scriptedcontrols) 1449 lock (scriptedcontrols)
1310 { 1450 {
1311 if (scriptedcontrols.Count > 0) 1451 if (scriptedcontrols.Count > 0)
@@ -1320,6 +1460,9 @@ namespace OpenSim.Region.Framework.Scenes
1320 1460
1321 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1461 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1322 { 1462 {
1463 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1464 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1465
1323 // TODO: This doesn't prevent the user from walking yet. 1466 // TODO: This doesn't prevent the user from walking yet.
1324 // Setting parent ID would fix this, if we knew what value 1467 // Setting parent ID would fix this, if we knew what value
1325 // to use. Or we could add a m_isSitting variable. 1468 // to use. Or we could add a m_isSitting variable.
@@ -1368,12 +1511,20 @@ namespace OpenSim.Region.Framework.Scenes
1368 if (actor.Flying != oldflying) 1511 if (actor.Flying != oldflying)
1369 update_movementflag = true; 1512 update_movementflag = true;
1370 1513
1514 if (m_animator.m_jumping) // add for jumping
1515 update_movementflag = true;
1516
1371 if (q != m_bodyRot) 1517 if (q != m_bodyRot)
1372 { 1518 {
1373 m_bodyRot = q; 1519 m_bodyRot = q;
1374 update_rotation = true; 1520 update_rotation = true;
1375 } 1521 }
1376 1522
1523 //guilty until proven innocent..
1524 bool Nudging = true;
1525 //Basically, if there is at least one non-nudge control then we don't need
1526 //to worry about stopping the avatar
1527
1377 if (m_parentID == 0) 1528 if (m_parentID == 0)
1378 { 1529 {
1379 bool bAllowUpdateMoveToPosition = false; 1530 bool bAllowUpdateMoveToPosition = false;
@@ -1388,9 +1539,12 @@ namespace OpenSim.Region.Framework.Scenes
1388 else 1539 else
1389 dirVectors = Dir_Vectors; 1540 dirVectors = Dir_Vectors;
1390 1541
1391 // The fact that m_movementflag is a byte needs to be fixed 1542 bool[] isNudge = GetDirectionIsNudge();
1392 // it really should be a uint 1543
1393 uint nudgehack = 250; 1544
1545
1546
1547
1394 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1548 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1395 { 1549 {
1396 if (((uint)flags & (uint)DCF) != 0) 1550 if (((uint)flags & (uint)DCF) != 0)
@@ -1400,40 +1554,28 @@ namespace OpenSim.Region.Framework.Scenes
1400 try 1554 try
1401 { 1555 {
1402 agent_control_v3 += dirVectors[i]; 1556 agent_control_v3 += dirVectors[i];
1403 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1557 if (isNudge[i] == false)
1558 {
1559 Nudging = false;
1560 }
1404 } 1561 }
1405 catch (IndexOutOfRangeException) 1562 catch (IndexOutOfRangeException)
1406 { 1563 {
1407 // Why did I get this? 1564 // Why did I get this?
1408 } 1565 }
1409 1566
1410 if ((m_movementflag & (byte)(uint)DCF) == 0) 1567 if ((m_movementflag & (uint)DCF) == 0)
1411 { 1568 {
1412 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1413 {
1414 m_movementflag |= (byte)nudgehack;
1415 }
1416 m_movementflag += (byte)(uint)DCF; 1569 m_movementflag += (byte)(uint)DCF;
1417 update_movementflag = true; 1570 update_movementflag = true;
1418 } 1571 }
1419 } 1572 }
1420 else 1573 else
1421 { 1574 {
1422 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1575 if ((m_movementflag & (uint)DCF) != 0)
1423 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1424 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1425 ) // This or is for Nudge forward
1426 { 1576 {
1427 m_movementflag -= ((byte)(uint)DCF); 1577 m_movementflag -= (byte)(uint)DCF;
1428
1429 update_movementflag = true; 1578 update_movementflag = true;
1430 /*
1431 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1432 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1433 {
1434 m_log.Debug("Removed Hack flag");
1435 }
1436 */
1437 } 1579 }
1438 else 1580 else
1439 { 1581 {
@@ -1442,7 +1584,6 @@ namespace OpenSim.Region.Framework.Scenes
1442 } 1584 }
1443 i++; 1585 i++;
1444 } 1586 }
1445
1446 //Paupaw:Do Proper PID for Autopilot here 1587 //Paupaw:Do Proper PID for Autopilot here
1447 if (bResetMoveToPosition) 1588 if (bResetMoveToPosition)
1448 { 1589 {
@@ -1477,6 +1618,9 @@ namespace OpenSim.Region.Framework.Scenes
1477 // Ignore z component of vector 1618 // Ignore z component of vector
1478 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1619 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1479 LocalVectorToTarget2D.Normalize(); 1620 LocalVectorToTarget2D.Normalize();
1621
1622 //We're not nudging
1623 Nudging = false;
1480 agent_control_v3 += LocalVectorToTarget2D; 1624 agent_control_v3 += LocalVectorToTarget2D;
1481 1625
1482 // update avatar movement flags. the avatar coordinate system is as follows: 1626 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1567,13 +1711,13 @@ namespace OpenSim.Region.Framework.Scenes
1567 // m_log.DebugFormat( 1711 // m_log.DebugFormat(
1568 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1712 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1569 1713
1570 AddNewMovement(agent_control_v3, q); 1714 AddNewMovement(agent_control_v3, q, Nudging);
1571 1715
1572 1716
1573 } 1717 }
1574 } 1718 }
1575 1719
1576 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1720 if (update_movementflag && !SitGround)
1577 Animator.UpdateMovementAnimations(); 1721 Animator.UpdateMovementAnimations();
1578 1722
1579 m_scene.EventManager.TriggerOnClientMovement(this); 1723 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1588,7 +1732,6 @@ namespace OpenSim.Region.Framework.Scenes
1588 m_sitAtAutoTarget = false; 1732 m_sitAtAutoTarget = false;
1589 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1733 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1590 //proxy.PCode = (byte)PCode.ParticleSystem; 1734 //proxy.PCode = (byte)PCode.ParticleSystem;
1591
1592 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1735 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1593 proxyObjectGroup.AttachToScene(m_scene); 1736 proxyObjectGroup.AttachToScene(m_scene);
1594 1737
@@ -1629,8 +1772,8 @@ namespace OpenSim.Region.Framework.Scenes
1629 return; 1772 return;
1630 } 1773 }
1631 m_moveToPositionInProgress = true; 1774 m_moveToPositionInProgress = true;
1632 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1775 m_moveToPositionTarget = new Vector3(locx, locy, locz + (m_appearance.AvatarHeight / 2.0f));
1633 } 1776 }
1634 catch (Exception ex) 1777 catch (Exception ex)
1635 { 1778 {
1636 //Why did I get this error? 1779 //Why did I get this error?
@@ -1652,7 +1795,7 @@ namespace OpenSim.Region.Framework.Scenes
1652 Velocity = Vector3.Zero; 1795 Velocity = Vector3.Zero;
1653 SendAvatarDataToAllAgents(); 1796 SendAvatarDataToAllAgents();
1654 1797
1655 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1798 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1656 } 1799 }
1657 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1800 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1658 m_requestedSitTargetUUID = UUID.Zero; 1801 m_requestedSitTargetUUID = UUID.Zero;
@@ -1689,25 +1832,22 @@ namespace OpenSim.Region.Framework.Scenes
1689 1832
1690 if (m_parentID != 0) 1833 if (m_parentID != 0)
1691 { 1834 {
1692 m_log.Debug("StandupCode Executed"); 1835 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1693 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1694 if (part != null) 1836 if (part != null)
1695 { 1837 {
1838 part.TaskInventory.LockItemsForRead(true);
1696 TaskInventoryDictionary taskIDict = part.TaskInventory; 1839 TaskInventoryDictionary taskIDict = part.TaskInventory;
1697 if (taskIDict != null) 1840 if (taskIDict != null)
1698 { 1841 {
1699 lock (taskIDict) 1842 foreach (UUID taskID in taskIDict.Keys)
1700 { 1843 {
1701 foreach (UUID taskID in taskIDict.Keys) 1844 UnRegisterControlEventsToScript(LocalId, taskID);
1702 { 1845 taskIDict[taskID].PermsMask &= ~(
1703 UnRegisterControlEventsToScript(LocalId, taskID); 1846 2048 | //PERMISSION_CONTROL_CAMERA
1704 taskIDict[taskID].PermsMask &= ~( 1847 4); // PERMISSION_TAKE_CONTROLS
1705 2048 | //PERMISSION_CONTROL_CAMERA
1706 4); // PERMISSION_TAKE_CONTROLS
1707 }
1708 } 1848 }
1709
1710 } 1849 }
1850 part.TaskInventory.LockItemsForRead(false);
1711 // Reset sit target. 1851 // Reset sit target.
1712 if (part.GetAvatarOnSitTarget() == UUID) 1852 if (part.GetAvatarOnSitTarget() == UUID)
1713 part.SitTargetAvatar = UUID.Zero; 1853 part.SitTargetAvatar = UUID.Zero;
@@ -1716,16 +1856,55 @@ namespace OpenSim.Region.Framework.Scenes
1716 m_parentPosition = part.GetWorldPosition(); 1856 m_parentPosition = part.GetWorldPosition();
1717 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1857 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1718 } 1858 }
1859 // part.GetWorldRotation() is the rotation of the object being sat on
1860 // Rotation is the sittiing Av's rotation
1861
1862 Quaternion partRot;
1863// if (part.LinkNum == 1)
1864// { // Root prim of linkset
1865// partRot = part.ParentGroup.RootPart.RotationOffset;
1866// }
1867// else
1868// { // single or child prim
1869
1870// }
1871 if (part == null) //CW: Part may be gone. llDie() for example.
1872 {
1873 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1874 }
1875 else
1876 {
1877 partRot = part.GetWorldRotation();
1878 }
1879
1880 Quaternion partIRot = Quaternion.Inverse(partRot);
1881
1882 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1883 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1719 1884
1885
1720 if (m_physicsActor == null) 1886 if (m_physicsActor == null)
1721 { 1887 {
1722 AddToPhysicalScene(false); 1888 AddToPhysicalScene(false);
1723 } 1889 }
1724 1890 //CW: If the part isn't null then we can set the current position
1725 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1891 if (part != null)
1726 m_parentPosition = Vector3.Zero; 1892 {
1727 1893 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1728 m_parentID = 0; 1894 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1895 part.IsOccupied = false;
1896 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1897 }
1898 else
1899 {
1900 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1901 AbsolutePosition = m_lastWorldPosition;
1902 }
1903
1904 m_parentPosition = Vector3.Zero;
1905 m_parentID = 0;
1906 m_linkedPrim = UUID.Zero;
1907 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1729 SendAvatarDataToAllAgents(); 1908 SendAvatarDataToAllAgents();
1730 m_requestedSitTargetID = 0; 1909 m_requestedSitTargetID = 0;
1731 if (m_physicsActor != null && m_appearance != null) 1910 if (m_physicsActor != null && m_appearance != null)
@@ -1734,7 +1913,6 @@ namespace OpenSim.Region.Framework.Scenes
1734 SetHeight(m_appearance.AvatarHeight); 1913 SetHeight(m_appearance.AvatarHeight);
1735 } 1914 }
1736 } 1915 }
1737
1738 Animator.TrySetMovementAnimation("STAND"); 1916 Animator.TrySetMovementAnimation("STAND");
1739 } 1917 }
1740 1918
@@ -1765,13 +1943,9 @@ namespace OpenSim.Region.Framework.Scenes
1765 Vector3 avSitOffSet = part.SitTargetPosition; 1943 Vector3 avSitOffSet = part.SitTargetPosition;
1766 Quaternion avSitOrientation = part.SitTargetOrientation; 1944 Quaternion avSitOrientation = part.SitTargetOrientation;
1767 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1945 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1768 1946 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1769 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1947 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1770 bool SitTargetisSet = 1948 if (SitTargetisSet && !SitTargetOccupied)
1771 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1772 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1773
1774 if (SitTargetisSet && SitTargetUnOccupied)
1775 { 1949 {
1776 //switch the target to this prim 1950 //switch the target to this prim
1777 return part; 1951 return part;
@@ -1785,85 +1959,167 @@ namespace OpenSim.Region.Framework.Scenes
1785 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1959 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1786 { 1960 {
1787 bool autopilot = true; 1961 bool autopilot = true;
1962 Vector3 autopilotTarget = new Vector3();
1963 Quaternion sitOrientation = Quaternion.Identity;
1788 Vector3 pos = new Vector3(); 1964 Vector3 pos = new Vector3();
1789 Quaternion sitOrientation = pSitOrientation;
1790 Vector3 cameraEyeOffset = Vector3.Zero; 1965 Vector3 cameraEyeOffset = Vector3.Zero;
1791 Vector3 cameraAtOffset = Vector3.Zero; 1966 Vector3 cameraAtOffset = Vector3.Zero;
1792 bool forceMouselook = false; 1967 bool forceMouselook = false;
1793 1968
1794 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1969 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1795 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1970 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1796 if (part != null) 1971 if (part == null) return;
1797 { 1972
1798 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1973 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1799 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1974 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1800 1975
1801 // Is a sit target available? 1976 // part is the prim to sit on
1802 Vector3 avSitOffSet = part.SitTargetPosition; 1977 // offset is the world-ref vector distance from that prim center to the click-spot
1803 Quaternion avSitOrientation = part.SitTargetOrientation; 1978 // UUID is the UUID of the Avatar doing the clicking
1804 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1979
1805 1980 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1806 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1981
1807 bool SitTargetisSet = 1982 // Is a sit target available?
1808 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1983 Vector3 avSitOffSet = part.SitTargetPosition;
1809 ( 1984 Quaternion avSitOrientation = part.SitTargetOrientation;
1810 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1985
1811 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1986 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1812 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1987 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1813 ) 1988 Quaternion partRot;
1814 )); 1989// if (part.LinkNum == 1)
1815 1990// { // Root prim of linkset
1816 if (SitTargetisSet && SitTargetUnOccupied) 1991// partRot = part.ParentGroup.RootPart.RotationOffset;
1817 { 1992// }
1818 part.SitTargetAvatar = UUID; 1993// else
1819 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1994// { // single or child prim
1820 sitOrientation = avSitOrientation; 1995 partRot = part.GetWorldRotation();
1821 autopilot = false; 1996// }
1822 } 1997 Quaternion partIRot = Quaternion.Inverse(partRot);
1823 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 1998//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1824 1999 // Sit analysis rewritten by KF 091125
1825 pos = part.AbsolutePosition + offset; 2000 if (SitTargetisSet) // scipted sit
1826 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 2001 {
1827 //{ 2002 if (!part.IsOccupied)
1828 // offset = pos; 2003 {
1829 //autopilot = false; 2004//Console.WriteLine("Scripted, unoccupied");
1830 //} 2005 part.SitTargetAvatar = UUID; // set that Av will be on it
1831 if (m_physicsActor != null) 2006 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1832 { 2007
1833 // If we're not using the client autopilot, we're immediately warping the avatar to the location 2008 Quaternion nrot = avSitOrientation;
1834 // We can remove the physicsActor until they stand up. 2009 if (!part.IsRoot)
1835 m_sitAvatarHeight = m_physicsActor.Size.Z;
1836
1837 if (autopilot)
1838 { 2010 {
1839 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2011 nrot = part.RotationOffset * avSitOrientation;
1840 {
1841 autopilot = false;
1842
1843 RemoveFromPhysicalScene();
1844 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1845 }
1846 } 2012 }
1847 else 2013 sitOrientation = nrot; // Change rotatione to the scripted one
2014 OffsetRotation = nrot;
2015 autopilot = false; // Jump direct to scripted llSitPos()
2016 }
2017 else
2018 {
2019//Console.WriteLine("Scripted, occupied");
2020 return;
2021 }
2022 }
2023 else // Not Scripted
2024 {
2025 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
2026 {
2027 // large prim & offset, ignore if other Avs sitting
2028// offset.Z -= 0.05f;
2029 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2030 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2031
2032//Console.WriteLine(" offset ={0}", offset);
2033//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2034//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2035
2036 }
2037 else // small offset
2038 {
2039//Console.WriteLine("Small offset");
2040 if (!part.IsOccupied)
2041 {
2042 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2043 autopilotTarget = part.AbsolutePosition;
2044//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2045 }
2046 else return; // occupied small
2047 } // end large/small
2048 } // end Scripted/not
2049
2050 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2051
2052 cameraAtOffset = part.GetCameraAtOffset();
2053 cameraEyeOffset = part.GetCameraEyeOffset();
2054 forceMouselook = part.GetForceMouselook();
2055 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2056 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2057
2058 if (m_physicsActor != null)
2059 {
2060 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2061 // We can remove the physicsActor until they stand up.
2062 m_sitAvatarHeight = m_physicsActor.Size.Z;
2063 if (autopilot)
2064 { // its not a scripted sit
2065// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2066 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1848 { 2067 {
2068 autopilot = false; // close enough
2069 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2070 Not using the part's position because returning the AV to the last known standing
2071 position is likely to be more friendly, isn't it? */
1849 RemoveFromPhysicalScene(); 2072 RemoveFromPhysicalScene();
1850 } 2073 Velocity = Vector3.Zero;
2074 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2075 } // else the autopilot will get us close
2076 }
2077 else
2078 { // its a scripted sit
2079 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2080 I *am* using the part's position this time because we have no real idea how far away
2081 the avatar is from the sit target. */
2082 RemoveFromPhysicalScene();
2083 Velocity = Vector3.Zero;
1851 } 2084 }
1852
1853 cameraAtOffset = part.GetCameraAtOffset();
1854 cameraEyeOffset = part.GetCameraEyeOffset();
1855 forceMouselook = part.GetForceMouselook();
1856 } 2085 }
1857 2086 else return; // physactor is null!
1858 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2087
1859 m_requestedSitTargetUUID = targetID; 2088 Vector3 offsetr; // = offset * partIRot;
2089 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2090 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2091 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2092 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2093 //offsetr = offset * partIRot;
2094//
2095 // else
2096 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2097 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2098 // (offset * partRot);
2099 // }
2100
2101//Console.WriteLine(" ");
2102//Console.WriteLine("link number ={0}", part.LinkNum);
2103//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2104//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2105//Console.WriteLine("Click offst ={0}", offset);
2106//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2107//Console.WriteLine("offsetr ={0}", offsetr);
2108//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2109//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2110
2111 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2112 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2113
2114 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1860 // This calls HandleAgentSit twice, once from here, and the client calls 2115 // This calls HandleAgentSit twice, once from here, and the client calls
1861 // HandleAgentSit itself after it gets to the location 2116 // HandleAgentSit itself after it gets to the location
1862 // It doesn't get to the location until we've moved them there though 2117 // It doesn't get to the location until we've moved them there though
1863 // which happens in HandleAgentSit :P 2118 // which happens in HandleAgentSit :P
1864 m_autopilotMoving = autopilot; 2119 m_autopilotMoving = autopilot;
1865 m_autoPilotTarget = pos; 2120 m_autoPilotTarget = autopilotTarget;
1866 m_sitAtAutoTarget = autopilot; 2121 m_sitAtAutoTarget = autopilot;
2122 m_initialSitTarget = autopilotTarget;
1867 if (!autopilot) 2123 if (!autopilot)
1868 HandleAgentSit(remoteClient, UUID); 2124 HandleAgentSit(remoteClient, UUID);
1869 } 2125 }
@@ -2158,47 +2414,130 @@ namespace OpenSim.Region.Framework.Scenes
2158 { 2414 {
2159 if (part != null) 2415 if (part != null)
2160 { 2416 {
2417//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2161 if (part.GetAvatarOnSitTarget() == UUID) 2418 if (part.GetAvatarOnSitTarget() == UUID)
2162 { 2419 {
2420//Console.WriteLine("Scripted Sit");
2421 // Scripted sit
2163 Vector3 sitTargetPos = part.SitTargetPosition; 2422 Vector3 sitTargetPos = part.SitTargetPosition;
2164 Quaternion sitTargetOrient = part.SitTargetOrientation; 2423 Quaternion sitTargetOrient = part.SitTargetOrientation;
2165
2166 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2167 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2168
2169 //Quaternion result = (sitTargetOrient * vq) * nq;
2170
2171 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2424 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2172 m_pos += SIT_TARGET_ADJUSTMENT; 2425 m_pos += SIT_TARGET_ADJUSTMENT;
2426 if (!part.IsRoot)
2427 {
2428 m_pos *= part.RotationOffset;
2429 }
2173 m_bodyRot = sitTargetOrient; 2430 m_bodyRot = sitTargetOrient;
2174 //Rotation = sitTargetOrient;
2175 m_parentPosition = part.AbsolutePosition; 2431 m_parentPosition = part.AbsolutePosition;
2176 2432 part.IsOccupied = true;
2177 //SendTerseUpdateToAllClients(); 2433 part.ParentGroup.AddAvatar(agentID);
2178 } 2434 }
2179 else 2435 else
2180 { 2436 {
2181 m_pos -= part.AbsolutePosition; 2437 // if m_avUnscriptedSitPos is zero then Av sits above center
2438 // Else Av sits at m_avUnscriptedSitPos
2439
2440 // Non-scripted sit by Kitto Flora 21Nov09
2441 // Calculate angle of line from prim to Av
2442 Quaternion partIRot;
2443// if (part.LinkNum == 1)
2444// { // Root prim of linkset
2445// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2446// }
2447// else
2448// { // single or child prim
2449 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2450// }
2451 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2452 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2453 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2454 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2455 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2456 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2457 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2458 // Av sits at world euler <0,0, z>, translated by part rotation
2459 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2460
2182 m_parentPosition = part.AbsolutePosition; 2461 m_parentPosition = part.AbsolutePosition;
2183 } 2462 part.IsOccupied = true;
2463 part.ParentGroup.AddAvatar(agentID);
2464 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2465 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2466 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2467 m_avUnscriptedSitPos; // adds click offset, if any
2468 //Set up raytrace to find top surface of prim
2469 Vector3 size = part.Scale;
2470 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2471 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2472 Vector3 down = new Vector3(0f, 0f, -1f);
2473//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2474 m_scene.PhysicsScene.RaycastWorld(
2475 start, // Vector3 position,
2476 down, // Vector3 direction,
2477 mag, // float length,
2478 SitAltitudeCallback); // retMethod
2479 } // end scripted/not
2184 } 2480 }
2185 else 2481 else // no Av
2186 { 2482 {
2187 return; 2483 return;
2188 } 2484 }
2189 } 2485 }
2190 m_parentID = m_requestedSitTargetID;
2191 2486
2487 //We want our offsets to reference the root prim, not the child we may have sat on
2488 if (!part.IsRoot)
2489 {
2490 m_parentID = part.ParentGroup.RootPart.LocalId;
2491 m_pos += part.OffsetPosition;
2492 }
2493 else
2494 {
2495 m_parentID = m_requestedSitTargetID;
2496 }
2497
2498 m_linkedPrim = part.UUID;
2499 if (part.GetAvatarOnSitTarget() != UUID)
2500 {
2501 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2502 }
2192 Velocity = Vector3.Zero; 2503 Velocity = Vector3.Zero;
2193 RemoveFromPhysicalScene(); 2504 RemoveFromPhysicalScene();
2194
2195 Animator.TrySetMovementAnimation(sitAnimation); 2505 Animator.TrySetMovementAnimation(sitAnimation);
2196 SendAvatarDataToAllAgents(); 2506 SendAvatarDataToAllAgents();
2197 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2198 // So we're also sending a terse update (which has avatar rotation)
2199 // [Update] We do now.
2200 //SendTerseUpdateToAllClients(); 2507 //SendTerseUpdateToAllClients();
2201 } 2508 }
2509
2510 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2511 {
2512 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2513 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2514 if(hitYN)
2515 {
2516 // m_pos = Av offset from prim center to make look like on center
2517 // m_parentPosition = Actual center pos of prim
2518 // collisionPoint = spot on prim where we want to sit
2519 // collisionPoint.Z = global sit surface height
2520 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2521 Quaternion partIRot;
2522// if (part.LinkNum == 1)
2523/// { // Root prim of linkset
2524// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2525// }
2526// else
2527// { // single or child prim
2528 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2529// }
2530 if (m_initialSitTarget != null)
2531 {
2532 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2533 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2534 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2535 m_pos += offset;
2536 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2537 }
2538
2539 }
2540 } // End SitAltitudeCallback KF.
2202 2541
2203 /// <summary> 2542 /// <summary>
2204 /// Event handler for the 'Always run' setting on the client 2543 /// Event handler for the 'Always run' setting on the client
@@ -2228,12 +2567,13 @@ namespace OpenSim.Region.Framework.Scenes
2228 /// </summary> 2567 /// </summary>
2229 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2568 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2230 /// <param name="rotation">The direction in which this avatar should now face. 2569 /// <param name="rotation">The direction in which this avatar should now face.
2231 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2570 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2232 { 2571 {
2233 if (m_isChildAgent) 2572 if (m_isChildAgent)
2234 { 2573 {
2235 // WHAT??? 2574 // WHAT???
2236 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2575 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2576
2237 return; 2577 return;
2238 } 2578 }
2239 2579
@@ -2242,15 +2582,26 @@ namespace OpenSim.Region.Framework.Scenes
2242 Rotation = rotation; 2582 Rotation = rotation;
2243 Vector3 direc = vec * rotation; 2583 Vector3 direc = vec * rotation;
2244 direc.Normalize(); 2584 direc.Normalize();
2585 PhysicsActor actor = m_physicsActor;
2586
2587 if (actor.Flying != m_flyingOld) // add for fly velocity control
2588 {
2589 m_flyingOld = actor.Flying; // add for fly velocity control
2590 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2591 }
2592
2593 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2594
2595 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2245 2596
2246 direc *= 0.03f * 128f * m_speedModifier; 2597 direc *= 0.03f * 128f * m_speedModifier;
2247 2598
2248 PhysicsActor actor = m_physicsActor;
2249 if (actor != null) 2599 if (actor != null)
2250 { 2600 {
2251 if (actor.Flying) 2601 if (actor.Flying)
2252 { 2602 {
2253 direc *= 4.0f; 2603// rm speed mod direc *= 4.0f;
2604 direc *= 5.2f; // for speed mod
2254 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2605 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2255 //bool colliding = (m_physicsActor.IsColliding==true); 2606 //bool colliding = (m_physicsActor.IsColliding==true);
2256 //if (controlland) 2607 //if (controlland)
@@ -2263,22 +2614,34 @@ namespace OpenSim.Region.Framework.Scenes
2263 // m_log.Info("[AGENT]: Stop FLying"); 2614 // m_log.Info("[AGENT]: Stop FLying");
2264 //} 2615 //}
2265 } 2616 }
2617 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2618 {
2619 direc *= 0.0f;
2620 }
2621 /* This jumping section removed to SPA
2266 else if (!actor.Flying && actor.IsColliding) 2622 else if (!actor.Flying && actor.IsColliding)
2267 { 2623 {
2268 if (direc.Z > 2.0f) 2624 if (direc.Z > 2.0f)
2269 { 2625 {
2270 direc.Z *= 3.0f; 2626 if(m_animator.m_animTickJump == -1)
2271 2627 {
2272 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2628 direc.Z *= 3.0f; // jump
2273 Animator.TrySetMovementAnimation("PREJUMP"); 2629 }
2274 Animator.TrySetMovementAnimation("JUMP"); 2630 else
2631 {
2632 direc.Z *= 0.1f; // prejump
2633 }
2634 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2635 Animator.TrySetMovementAnimation("PREJUMP");
2636 Animator.TrySetMovementAnimation("JUMP");
2637 * /
2275 } 2638 }
2276 } 2639 } */
2277 } 2640 }
2278 2641
2279 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2642 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2280 m_forceToApply = direc; 2643 m_forceToApply = direc;
2281 2644 m_isNudging = Nudging;
2282 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2645 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2283 } 2646 }
2284 2647
@@ -2327,6 +2690,9 @@ namespace OpenSim.Region.Framework.Scenes
2327 2690
2328 CheckForSignificantMovement(); // sends update to the modules. 2691 CheckForSignificantMovement(); // sends update to the modules.
2329 } 2692 }
2693
2694 //Sending prim updates AFTER the avatar terse updates are sent
2695 SendPrimUpdates();
2330 } 2696 }
2331 2697
2332 #endregion 2698 #endregion
@@ -3086,6 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes
3086 m_callbackURI = cAgent.CallbackURI; 3452 m_callbackURI = cAgent.CallbackURI;
3087 3453
3088 m_pos = cAgent.Position; 3454 m_pos = cAgent.Position;
3455
3089 m_velocity = cAgent.Velocity; 3456 m_velocity = cAgent.Velocity;
3090 m_CameraCenter = cAgent.Center; 3457 m_CameraCenter = cAgent.Center;
3091 m_CameraAtAxis = cAgent.AtAxis; 3458 m_CameraAtAxis = cAgent.AtAxis;
@@ -3204,20 +3571,45 @@ namespace OpenSim.Region.Framework.Scenes
3204 /// </summary> 3571 /// </summary>
3205 public override void UpdateMovement() 3572 public override void UpdateMovement()
3206 { 3573 {
3207 if (m_forceToApply.HasValue) 3574 if (Animator!=null) // add for jumping
3208 { 3575 { // add for jumping
3209 Vector3 force = m_forceToApply.Value; 3576 // if (!m_animator.m_jumping) // add for jumping
3577 // { // add for jumping
3210 3578
3211 m_updateflag = true; 3579 if (m_forceToApply.HasValue) // this section realigned
3212 3580 {
3213 // The magic constant 0.95f seems to make walking feel less jerky,
3214 // probably because it hackishly accounts for the overall latency of
3215 // these Velocity updates -- Diva
3216 Velocity = force * .95F;
3217 3581
3218 m_forceToApply = null; 3582 Vector3 force = m_forceToApply.Value;
3219 } 3583 m_updateflag = true;
3220 } 3584if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3585 Velocity = force;
3586//Console.WriteLine("UM1 {0}", Velocity);
3587 m_forceToApply = null;
3588 }
3589 else
3590 {
3591 if (m_isNudging)
3592 {
3593 Vector3 force = Vector3.Zero;
3594
3595 m_updateflag = true;
3596if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3597 Velocity = force;
3598//Console.WriteLine("UM2 {0}", Velocity);
3599 m_isNudging = false;
3600 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3601 }
3602 else // add for jumping
3603 { // add for jumping
3604 Vector3 force = Vector3.Zero; // add for jumping
3605if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3606//Console.WriteLine("UM3 {0}", Velocity);
3607 Velocity = force; // add for jumping
3608 }
3609 }
3610 // } // end realign
3611 } // add for jumping
3612 } // add for jumping
3221 3613
3222 /// <summary> 3614 /// <summary>
3223 /// Adds a physical representation of the avatar to the Physics plugin 3615 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3231,10 +3623,8 @@ namespace OpenSim.Region.Framework.Scenes
3231 3623
3232 Vector3 pVec = AbsolutePosition; 3624 Vector3 pVec = AbsolutePosition;
3233 3625
3234 // Old bug where the height was in centimeters instead of meters
3235 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3626 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3236 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3627 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3237
3238 scene.AddPhysicsActorTaint(m_physicsActor); 3628 scene.AddPhysicsActorTaint(m_physicsActor);
3239 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3629 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3240 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3630 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3258,18 +3648,29 @@ namespace OpenSim.Region.Framework.Scenes
3258 { 3648 {
3259 if (e == null) 3649 if (e == null)
3260 return; 3650 return;
3261 3651
3262 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3652 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3263 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3264 // as of this comment the interval is set in AddToPhysicalScene 3653 // as of this comment the interval is set in AddToPhysicalScene
3265 if (Animator!=null) 3654 if (Animator!=null)
3266 Animator.UpdateMovementAnimations(); 3655 {
3656 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3657 { // else its will lock out other animation changes, like ground sit.
3658 Animator.UpdateMovementAnimations();
3659 m_updateCount--;
3660 }
3661 }
3267 3662
3268 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3663 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3269 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3664 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3270 3665
3271 CollisionPlane = Vector4.UnitW; 3666 CollisionPlane = Vector4.UnitW;
3272 3667
3668 if (m_lastColCount != coldata.Count)
3669 {
3670 m_updateCount = UPDATE_COUNT;
3671 m_lastColCount = coldata.Count;
3672 }
3673
3273 if (coldata.Count != 0 && Animator != null) 3674 if (coldata.Count != 0 && Animator != null)
3274 { 3675 {
3275 switch (Animator.CurrentMovementAnimation) 3676 switch (Animator.CurrentMovementAnimation)
@@ -3299,6 +3700,148 @@ namespace OpenSim.Region.Framework.Scenes
3299 } 3700 }
3300 } 3701 }
3301 3702
3703 List<uint> thisHitColliders = new List<uint>();
3704 List<uint> endedColliders = new List<uint>();
3705 List<uint> startedColliders = new List<uint>();
3706
3707 foreach (uint localid in coldata.Keys)
3708 {
3709 thisHitColliders.Add(localid);
3710 if (!m_lastColliders.Contains(localid))
3711 {
3712 startedColliders.Add(localid);
3713 }
3714 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3715 }
3716
3717 // calculate things that ended colliding
3718 foreach (uint localID in m_lastColliders)
3719 {
3720 if (!thisHitColliders.Contains(localID))
3721 {
3722 endedColliders.Add(localID);
3723 }
3724 }
3725 //add the items that started colliding this time to the last colliders list.
3726 foreach (uint localID in startedColliders)
3727 {
3728 m_lastColliders.Add(localID);
3729 }
3730 // remove things that ended colliding from the last colliders list
3731 foreach (uint localID in endedColliders)
3732 {
3733 m_lastColliders.Remove(localID);
3734 }
3735
3736 // do event notification
3737 if (startedColliders.Count > 0)
3738 {
3739 ColliderArgs StartCollidingMessage = new ColliderArgs();
3740 List<DetectedObject> colliding = new List<DetectedObject>();
3741 foreach (uint localId in startedColliders)
3742 {
3743 if (localId == 0)
3744 continue;
3745
3746 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3747 string data = "";
3748 if (obj != null)
3749 {
3750 DetectedObject detobj = new DetectedObject();
3751 detobj.keyUUID = obj.UUID;
3752 detobj.nameStr = obj.Name;
3753 detobj.ownerUUID = obj.OwnerID;
3754 detobj.posVector = obj.AbsolutePosition;
3755 detobj.rotQuat = obj.GetWorldRotation();
3756 detobj.velVector = obj.Velocity;
3757 detobj.colliderType = 0;
3758 detobj.groupUUID = obj.GroupID;
3759 colliding.Add(detobj);
3760 }
3761 }
3762
3763 if (colliding.Count > 0)
3764 {
3765 StartCollidingMessage.Colliders = colliding;
3766
3767 foreach (SceneObjectGroup att in Attachments)
3768 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3769 }
3770 }
3771
3772 if (endedColliders.Count > 0)
3773 {
3774 ColliderArgs EndCollidingMessage = new ColliderArgs();
3775 List<DetectedObject> colliding = new List<DetectedObject>();
3776 foreach (uint localId in endedColliders)
3777 {
3778 if (localId == 0)
3779 continue;
3780
3781 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3782 string data = "";
3783 if (obj != null)
3784 {
3785 DetectedObject detobj = new DetectedObject();
3786 detobj.keyUUID = obj.UUID;
3787 detobj.nameStr = obj.Name;
3788 detobj.ownerUUID = obj.OwnerID;
3789 detobj.posVector = obj.AbsolutePosition;
3790 detobj.rotQuat = obj.GetWorldRotation();
3791 detobj.velVector = obj.Velocity;
3792 detobj.colliderType = 0;
3793 detobj.groupUUID = obj.GroupID;
3794 colliding.Add(detobj);
3795 }
3796 }
3797
3798 if (colliding.Count > 0)
3799 {
3800 EndCollidingMessage.Colliders = colliding;
3801
3802 foreach (SceneObjectGroup att in Attachments)
3803 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3804 }
3805 }
3806
3807 if (thisHitColliders.Count > 0)
3808 {
3809 ColliderArgs CollidingMessage = new ColliderArgs();
3810 List<DetectedObject> colliding = new List<DetectedObject>();
3811 foreach (uint localId in thisHitColliders)
3812 {
3813 if (localId == 0)
3814 continue;
3815
3816 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3817 string data = "";
3818 if (obj != null)
3819 {
3820 DetectedObject detobj = new DetectedObject();
3821 detobj.keyUUID = obj.UUID;
3822 detobj.nameStr = obj.Name;
3823 detobj.ownerUUID = obj.OwnerID;
3824 detobj.posVector = obj.AbsolutePosition;
3825 detobj.rotQuat = obj.GetWorldRotation();
3826 detobj.velVector = obj.Velocity;
3827 detobj.colliderType = 0;
3828 detobj.groupUUID = obj.GroupID;
3829 colliding.Add(detobj);
3830 }
3831 }
3832
3833 if (colliding.Count > 0)
3834 {
3835 CollidingMessage.Colliders = colliding;
3836
3837 lock (m_attachments)
3838 {
3839 foreach (SceneObjectGroup att in m_attachments)
3840 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3841 }
3842 }
3843 }
3844
3302 if (m_invulnerable) 3845 if (m_invulnerable)
3303 return; 3846 return;
3304 3847
@@ -3724,6 +4267,39 @@ namespace OpenSim.Region.Framework.Scenes
3724 return; 4267 return;
3725 } 4268 }
3726 4269
4270 XmlDocument doc = new XmlDocument();
4271 string stateData = String.Empty;
4272
4273 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4274 if (attServ != null)
4275 {
4276 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4277 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4278 if (stateData != String.Empty)
4279 {
4280 try
4281 {
4282 doc.LoadXml(stateData);
4283 }
4284 catch { }
4285 }
4286 }
4287
4288 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4289
4290 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4291 if (nodes.Count > 0)
4292 {
4293 foreach (XmlNode n in nodes)
4294 {
4295 XmlElement elem = (XmlElement)n;
4296 string itemID = elem.GetAttribute("ItemID");
4297 string xml = elem.InnerXml;
4298
4299 itemData[new UUID(itemID)] = xml;
4300 }
4301 }
4302
3727 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4303 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3728 foreach (AvatarAttachment attach in attachments) 4304 foreach (AvatarAttachment attach in attachments)
3729 { 4305 {
@@ -3744,7 +4320,30 @@ namespace OpenSim.Region.Framework.Scenes
3744 4320
3745 try 4321 try
3746 { 4322 {
3747 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4323 string xmlData;
4324 XmlDocument d = new XmlDocument();
4325 UUID asset;
4326 if (itemData.TryGetValue(itemID, out xmlData))
4327 {
4328 d.LoadXml(xmlData);
4329 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4330
4331 // Rez from inventory
4332 asset
4333 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4334
4335 }
4336 else
4337 {
4338 // Rez from inventory (with a null doc to let
4339 // CHANGED_OWNER happen)
4340 asset
4341 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4342 }
4343
4344 m_log.InfoFormat(
4345 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4346 p, itemID, asset);
3748 } 4347 }
3749 catch (Exception e) 4348 catch (Exception e)
3750 { 4349 {
@@ -3777,6 +4376,15 @@ namespace OpenSim.Region.Framework.Scenes
3777 m_reprioritization_called = false; 4376 m_reprioritization_called = false;
3778 } 4377 }
3779 } 4378 }
4379
4380 private Vector3 Quat2Euler(Quaternion rot){
4381 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4382 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4383 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4384 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4385 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4386 return(new Vector3(x,y,z));
4387 }
3780 4388
3781 public void SaveChangedAttachments() 4389 public void SaveChangedAttachments()
3782 { 4390 {